/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.javahispano.javacup.tacticas_aceptadas.Sito10.pringaos;

import java.util.LinkedList;
import java.util.List;
import org.javahispano.javacup.modelo.Comando;
import org.javahispano.javacup.modelo.ComandoGolpearBalon;
import org.javahispano.javacup.modelo.ComandoIrA;
import org.javahispano.javacup.modelo.Constantes;
import org.javahispano.javacup.modelo.Posicion;
import org.javahispano.javacup.modelo.SituacionPartido;
import org.javahispano.javacup.modelo.Tactica;
import org.javahispano.javacup.modelo.TacticaDetalle;

/**
 *
 * @author Dou
 */
public class Pringaos implements Tactica {
    PringaosDetalle detalle = new PringaosDetalle();
    LinkedList<Comando> comandos = new LinkedList<Comando>();
	int tactica_actual, tactica_anterior;
    int []marca_mio = new int[11];
    int []marca_rival = new int[11];
    int [][]tipo_jugadores ={ 
							{ConstantesPringaos.PORTERO,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.MEDIOCENTRO_DEFENSIVO,
                            ConstantesPringaos.MEDIOCENTRO_OFENSIVO,
                            ConstantesPringaos.MEDIOCENTRO_OFENSIVO,
                            ConstantesPringaos.DELANTERO},
							{ConstantesPringaos.PORTERO,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.MEDIOCENTRO_DEFENSIVO,
                            ConstantesPringaos.MEDIOCENTRO_OFENSIVO,
                            ConstantesPringaos.MEDIOCENTRO_OFENSIVO,
                            ConstantesPringaos.MEDIOCENTRO_OFENSIVO,
                            ConstantesPringaos.DELANTERO},
							{ConstantesPringaos.PORTERO,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.MEDIOCENTRO_DEFENSIVO,
                            ConstantesPringaos.MEDIOCENTRO_OFENSIVO,
                            ConstantesPringaos.MEDIOCENTRO_OFENSIVO,
                            ConstantesPringaos.MEDIOCENTRO_OFENSIVO,
                            ConstantesPringaos.DELANTERO,
                            ConstantesPringaos.DELANTERO},
							{ConstantesPringaos.PORTERO,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.MEDIOCENTRO_DEFENSIVO,
                            ConstantesPringaos.MEDIOCENTRO_OFENSIVO,
                            ConstantesPringaos.MEDIOCENTRO_OFENSIVO,
                            ConstantesPringaos.DELANTERO,
                            ConstantesPringaos.DELANTERO,
                            ConstantesPringaos.DELANTERO},
							{ConstantesPringaos.DELANTERO,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.DEFENSA,
                            ConstantesPringaos.MEDIOCENTRO_DEFENSIVO,
                            ConstantesPringaos.MEDIOCENTRO_OFENSIVO,
                            ConstantesPringaos.MEDIOCENTRO_OFENSIVO,
                            ConstantesPringaos.DELANTERO,
                            ConstantesPringaos.DELANTERO,
                            ConstantesPringaos.DELANTERO}};
							

    Posicion []mios = new Posicion[11];
    Posicion []ellos = new Posicion[11];


    Posicion alineaciones[][]=new Posicion[][]{
	{ // 0
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-31.082089552238806),
        new Posicion(11.16030534351145,-31.6044776119403),
        new Posicion(23.776223776223777,-27.556561085972852),
        new Posicion(-24.727272727272727,-27.31900452488688),
        new Posicion(8.55944055944056,-10.690045248868778),
        new Posicion(-10.461538461538462,-10.452488687782806),
        new Posicion(14.74125874125874,3.088235294117647),
        new Posicion(-17.832167832167833,2.8506787330316743),
        new Posicion(-0.2595419847328244,19.067164179104477),
        new Posicion(-0.2595419847328244,35.78358208955224)
    },
	{ // 1
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-19.46564885496183,-31.6044776119403),
        new Posicion(0.2595419847328244,-31.082089552238806),
        new Posicion(19.984732824427482,-31.6044776119403),
        new Posicion(10.223776223776223,-11.64027149321267),
        new Posicion(-10.937062937062937,-11.877828054298643),
        new Posicion(-20.685314685314687,6.176470588235294),
        new Posicion(19.25874125874126,7.364253393665159),
        new Posicion(-0.7132867132867133,19.479638009049776),
        new Posicion(-8.223776223776223,35.8710407239819),
        new Posicion(8.461538461538462,36.34615384615385)
    },
	{ // 2
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-7.846153846153847,-31.59502262443439),
        new Posicion(8.083916083916083,-31.59502262443439),
        new Posicion(19.020979020979023,-21.61764705882353),
        new Posicion(-19.734265734265733,-21.61764705882353),
        new Posicion(0.0,-6.176470588235294),
        new Posicion(-17.356643356643357,7.839366515837104),
        new Posicion(18.06993006993007,7.839366515837104),
        new Posicion(0.0,19.2420814479638),
        new Posicion(-8.510489510489512,36.34615384615385),
        new Posicion(8.034965034965035,36.82126696832579)
    },
    { // 3
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.174825174825173,-26.131221719457013),
        new Posicion(10.461538461538462,-26.606334841628957),
        new Posicion(17.356643356643357,-10.214932126696834),
        new Posicion(-16.88111888111888,-11.165158371040723),
        new Posicion(0.7132867132867133,0.0),
        new Posicion(10.223776223776223,20.429864253393667),
        new Posicion(-8.321678321678322,20.667420814479637),
        new Posicion(-8.461538461538462,36.34615384615385),
        new Posicion(0.4755244755244755,36.34615384615385),
        new Posicion(8.174825174825173,36.58371040723982)
    },
	{ // 4
        new Posicion(4.041958041958042,38.95927601809955),
        new Posicion(-11.174825174825173,-26.131221719457013),
        new Posicion(10.461538461538462,-26.606334841628957),
        new Posicion(17.356643356643357,-10.214932126696834),
        new Posicion(-16.88111888111888,-11.165158371040723),
        new Posicion(0.7132867132867133,0.0),
        new Posicion(10.223776223776223,20.429864253393667),
        new Posicion(-8.321678321678322,20.667420814479637),
        new Posicion(-8.461538461538462,36.34615384615385),
        new Posicion(-3.5664335664335667,38.95927601809955),
        new Posicion(8.174825174825173,36.58371040723982)
    },
	{ // 5
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-35.78358208955224),
        new Posicion(12.717557251908397,-35.26119402985075),
        new Posicion(28.290076335877863,-28.470149253731343),
        new Posicion(-28.290076335877863,-28.470149253731343),
        new Posicion(14.793893129770993,-18.544776119402986),
        new Posicion(-17.389312977099234,-19.58955223880597),
        new Posicion(-23.618320610687025,-0.7835820895522387),
        new Posicion(5.969465648854961,-5.485074626865671),
        new Posicion(0.2595419847328244,-0.26119402985074625),
        new Posicion(22.580152671755727,-1.3059701492537314)
    },
    { // 6
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-35.78358208955224),
        new Posicion(12.717557251908397,-35.26119402985075),
        new Posicion(28.290076335877863,-28.470149253731343),
        new Posicion(-28.290076335877863,-28.470149253731343),
        new Posicion(14.793893129770993,-18.544776119402986),
        new Posicion(-17.389312977099234,-19.58955223880597),
        new Posicion(-23.618320610687025,-0.7835820895522387),
        new Posicion(6.4885496183206115,-6.529850746268657),
        new Posicion(-6.4885496183206115,-6.529850746268657),
        new Posicion(22.580152671755727,-1.3059701492537314)
    }};

    public Pringaos() {
        for(int i = 0; i < 11; i++) {
            marca_mio[i] = -1;
            marca_rival[i] = -1;
        }
		
	tactica_actual = 1;
	tactica_anterior = 1;
    }

    @Override
    public TacticaDetalle getDetalle() {
        return detalle;
    }

    @Override
    public List<Comando> ejecutar(SituacionPartido sp) {
        int i;
        int diferencia_goles;

        comandos.clear();
        mios = sp.misJugadores();
        ellos = sp.rivales();
		diferencia_goles = sp.golesPropios() - sp.golesRival();

        switch(sp.iteracion()) {
            case 1440:
                if (diferencia_goles < 0) tactica_actual++;
                break;
            case 2160:
                if (diferencia_goles < 0) tactica_actual++;
                break;
            case 2880:
               	if (diferencia_goles < 0) tactica_actual++;
                else if (diferencia_goles == 1) tactica_actual--;
                break;                
        }	

        double distancia_a_jugador = 99999, distancia_temp;
        int temp = 0;
        int temp2 = 0;
		int f;

        for(i = 0; i < 11; i++){
            if (PuedoRematar(sp.puedenRematar(), i)) {
                if (EstoyEnZonaGol(sp.misJugadores()[i])) { 
					for(f = 0; f < 11; f++) {
                                            if (sp.detalleJugadoresRivales()[f].esPortero()) break;
					}
					Chutar(i, ellos[f]);
				}
                else Pasar(i, mios);
            } else {
                distancia_temp = sp.balon().distancia(sp.misJugadores()[i]);
                if (distancia_temp < distancia_a_jugador) {
                    distancia_a_jugador = distancia_temp;
                    temp2 = i;
                }
                switch(tipo_jugadores[tactica_actual][i]) {
                    case ConstantesPringaos.PORTERO:
                        double porx = Math.max(-3, sp.balon().getX());
                        porx = Math.min(3, porx);
                        comandos.add(new ComandoIrA(i, new Posicion(porx, -51.5)));
                        break;
                    case ConstantesPringaos.DEFENSA:
                        if (marca_mio[i] == -1) {
                            temp = BuscaRivalParaMarcar(sp.rivales(), sp.misJugadores()[i]);
                            if (temp != -1) {
                                marca_mio[i] = temp;
                                marca_rival[temp] = i;
                                Marcar(i, ellos[temp], sp.balon());
                            } else {
                                if (sp.balon().getY() <= ConstantesPringaos.LINEA_DEFENSA.getY()) {
                                    comandos.add(new ComandoIrA(i, sp.balon()));
                                } else {
                                    comandos.add(new ComandoIrA(i, alineaciones[tactica_actual][i]));
                                }
                            }
                        } else {
                            if (sp.rivales()[marca_mio[i]].getY() > ConstantesPringaos.LINEA_DEFENSA.getY()) {
                                marca_rival[marca_mio[i]] = -1;
                                marca_mio[i] = -1;
                                if (sp.balon().getY() <= ConstantesPringaos.LINEA_DEFENSA.getY()) {
                                    comandos.add(new ComandoIrA(i, sp.balon()));
                                } else {
                                    comandos.add(new ComandoIrA(i, alineaciones[tactica_actual][i]));
                                }
                            } else {
                                Marcar(i, ellos[marca_mio[i]], sp.balon());
                            }
                        }
                        break;
                    case ConstantesPringaos.MEDIOCENTRO_DEFENSIVO:
                        comandos.add(new ComandoIrA(i, sp.balon()));
                        break;
                    case ConstantesPringaos.MEDIOCENTRO_OFENSIVO:
                        Desmarcar(i);
                        break;
                    case ConstantesPringaos.DELANTERO:
                        Desmarcar(i);
                        break;
                }
            }
        }

        if (sp.puedenRematar().length == 0) comandos.add(new ComandoIrA(temp2, sp.balon()));

        return comandos;
    }

    @Override
    public Posicion[] getPosicionSaca(SituacionPartido sp) {
        return alineaciones[5];
    }

    @Override
    public Posicion[] getPosicionRecive(SituacionPartido sp) {
        return alineaciones[6];
    }

    public boolean EstoyEnZonaGol(Posicion p) {
        double distancia = p.distancia(Constantes.centroArcoSup);
        if (distancia <= ConstantesPringaos.RADIO_ZONA_GOL) return true;
        return false;
    }

    public void Chutar(int i, Posicion p) {
		double distancia_palo_izq, distancia_palo_der;
		
		distancia_palo_izq = p.distancia(Constantes.posteIzqArcoSup);
		distancia_palo_der = p.distancia(Constantes.posteDerArcoSup);
		if (distancia_palo_izq > distancia_palo_der) {
			comandos.add(new ComandoGolpearBalon(i, new Posicion(Constantes.posteIzqArcoSup.getX() + 1.0, Constantes.posteIzqArcoSup.getY()), 1, 20.0));
		} else {
			comandos.add(new ComandoGolpearBalon(i, new Posicion(Constantes.posteDerArcoSup.getX() - 1.0, Constantes.posteIzqArcoSup.getY()), 1, 20.0));
		}
    }

    public boolean PuedoRematar(int []jugadores, int i) {
        for(int f : jugadores) {
            if (f == i) return true;
        }
        return false;
    }

    public void Pasar(int i, Posicion[] mios) {
        double puntuacion, puntuacion_temp;
        int temp;
        int f;

        puntuacion = -1;
        temp = 10;
        for(f = 0; f < 11; f++) {
            puntuacion_temp = ConstantesPringaos.PASE_CAMPO_CONTRARIO +
                              ConstantesPringaos.PASE_DELANTE +
                              ConstantesPringaos.PASE_SEGURO +
                              ConstantesPringaos.PASE_ZONA_GOL;
            if (mios[f].getY() < mios[i].getY()) {
                puntuacion_temp -= ConstantesPringaos.PASE_DELANTE;
            }
            if (mios[f].getY() < 0) {
                puntuacion_temp -= ConstantesPringaos.PASE_CAMPO_CONTRARIO;
            }
            if (mios[f].getY() < ConstantesPringaos.RADIO_ZONA_GOL) {
                puntuacion_temp -= ConstantesPringaos.PASE_ZONA_GOL;
            }
            if ((puntuacion < puntuacion_temp) && (i != f)) {
                puntuacion = puntuacion_temp;
                temp = f;
            }
        }

        if (mios[i].distancia(mios[temp]) > 18.0)
            comandos.add(new ComandoGolpearBalon(i, mios[temp], 1, false));
        else
            comandos.add(new ComandoGolpearBalon(i, mios[temp], 0.70, false));
    }

    public int BuscaRivalParaMarcar(Posicion []rivales, Posicion pos) {
        double distancia = 99999, temp;
        int rival = -1;

        for(int i = 0; i < 11; i++) {
            if ((marca_rival[i] == -1) && (rivales[i].getY() <= ConstantesPringaos.LINEA_DEFENSA.getY())) {
               temp = pos.distancia(new Posicion(rivales[i].getX(), rivales[i].getY()));
               if (distancia > temp) {
                  distancia = temp;
                  rival = i;
               }
            }
        }

        return rival;
    }

    public void Marcar(int mio, Posicion rival, Posicion balon) {
        double x, y;

        x = rival.getX();
        y = rival.getY();
        if (balon.getX() < x) {
            x -= ConstantesPringaos.RADIO_PRESION;
        } else {
            x += ConstantesPringaos.RADIO_PRESION;
        }
        if (balon.getY() < y) {
            y -= ConstantesPringaos.RADIO_PRESION;
        } else {
            y += ConstantesPringaos.RADIO_PRESION;
        }

        comandos.add(new ComandoIrA(mio, new Posicion(x, y)));
    }

    public void Desmarcar(int mio) {
        boolean marcado;
        double dx, dy;

        marcado = false;
        for(int i = 0; (i < 11) && (!marcado); i++) {
            if (mios[mio].distancia(ellos[i]) < ConstantesPringaos.RADIO_ACCION) marcado = true;
        }
        if (marcado) {
            dx = alineaciones[tactica_actual][mio].getX() + Math.random() * ConstantesPringaos.RADIO_ACCION;
            dy = alineaciones[tactica_actual][mio].getY() + Math.random() * ConstantesPringaos.RADIO_ACCION;
            comandos.add(new ComandoIrA(mio, new Posicion(dx, dy)));
        } else {
            comandos.add(new ComandoIrA(mio, alineaciones[tactica_actual][mio]));
        }
    }
}
